// I found this code as a VB .NET example at
// http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=4038&lngWId=10.

using System.Collections;

namespace RideMe.Core
{
    public class WordFormatter
    {
        private enum Rules : int
        {
            Rule1,
            Rule2,
            Rule3,
            Rule4,
            Rule5,
            Rule6,
            Rule7A,
            Rule7B
        }

        private static ArrayList _Consonants = new ArrayList(new string[] { "b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "z" });
        private static ArrayList _vowels = new ArrayList(new string[] { "a", "e", "i", "o", "u", "y" });

        /// <summary>
        /// Returns the plural form of a word.
        /// </summary>
        /// <param name="noun"></param>
        /// <returns></returns>
        public static string Pluralize(string noun)
        {
            try
            {
                string endingLetters = noun.ToLower().Substring(noun.Length - 2, 2);

                Rules pluralRule = ApplyRules(endingLetters);

                if (pluralRule == Rules.Rule2)
                {
                    return noun + "es";
                }
                else if (pluralRule == Rules.Rule3)
                {
                    return noun + "s";
                }
                else if (pluralRule == Rules.Rule4)
                {
                    return noun.TrimEnd('y') + "ies";
                }
                else if (pluralRule == Rules.Rule5)
                {
                    return noun.TrimEnd("is".ToCharArray()) + "es";
                }
                else if (pluralRule == Rules.Rule6)
                {
                    return noun.TrimEnd("fe".ToCharArray()) + "ves";
                }
                else if (pluralRule == Rules.Rule7A)
                {
                    return noun + "s";
                }
                else if (pluralRule == Rules.Rule7B)
                {
                    return noun + "s";
                }
                else
                {
                    return noun + "s";
                }
            }
            catch
            {
                return noun;
            }
        }

        /// <summary>
        ///  Returns the singular form of a word.
        /// </summary>
        /// <param name="noun"></param>
        /// <returns></returns>
        public static string Singularize(string noun)
        {
            try
            {
                string endingLetters = noun.ToLower().Substring(noun.Length - 3, 3);

                Rules pluralRule = ApplyRules(endingLetters);

                if (endingLetters == "ies")
                {
                    return noun.TrimEnd("ies".ToCharArray()) + "y";
                }
                if (endingLetters == "ves")
                {
                    return noun.TrimEnd("ves".ToCharArray()) + "f";
                }
                if (endingLetters == "ses")
                {
                    return noun.TrimEnd("ses".ToCharArray()) + "s";
                }
                if (endingLetters == "oes")
                {
                    return noun.TrimEnd("oes".ToCharArray()) + "o";
                }
                return noun.TrimEnd('s');
            }
            catch
            {
                return noun;
            }
        }

        /// <summary>
        /// Applies formatting rules.
        /// </summary>
        /// <param name="endLetters"></param>
        /// <returns></returns>
        private static Rules ApplyRules(string endLetters)
        {
            char leftChar = System.Convert.ToChar(endLetters.ToLower().Substring(0, 1));
            char rightChar = System.Convert.ToChar(endLetters.ToLower().Substring(endLetters.Length - 1, 1));
            if ((IsVowel(leftChar)) && (rightChar == 'o'))
            {
                return Rules.Rule7A;
            }
            if ((IsConsonant(leftChar)) && (rightChar == 'o'))
            {
                return Rules.Rule7B;
            }
            if (rightChar == System.Convert.ToChar('f'))
            {
                return Rules.Rule6;
            }
            if (endLetters == "is")
            {
                return Rules.Rule5;
            }
            if ((IsConsonant(leftChar)) && (rightChar == System.Convert.ToChar('y')))
            {
                return Rules.Rule4;
            }
            if ((IsVowel(leftChar)) && (rightChar == 'y'))
            {
                return Rules.Rule3;
            }
            if ((rightChar == 's') || (rightChar == 'z') || (rightChar == 'x') || (endLetters == "ch") || (endLetters == "sh"))
            {
                return Rules.Rule2;
            }
            return Rules.Rule1;
        }

        /// <summary>
        ///  Returns whether the letter is a vowel.
        /// </summary>
        /// <param name="Letter"></param>
        /// <returns></returns>
        private static bool IsVowel(char letter)
        {
            if (_vowels.Contains(letter.ToString()))
            {
                return true;
            }

            return false;
        }

        /// <summary>
        /// Returns whether this is a consonant or not.
        /// </summary>
        /// <param name="Letter"></param>
        /// <returns></returns>
        private static bool IsConsonant(char letter)
        {
            if (_Consonants.Contains(letter.ToString()))
            {
                return true;
            }

            return false;
        }
    }
}